home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char sccsid[] = "@(#)spline.c 93/01/20 XLOCK";
- #endif
-
- /* spline.c - Bouncing Spline for xlock, the X Window System lockscreen
- *
- * Copyright (c) 1993 by Cor Bosman. (bosman@fwi.uva.nl)
- *
- * See xlock.c for copying information.
- *
- * 21-Jan-93: Converted kurvp1 and kurvp2 to C from pascal.
- * 20-Jan-93: Written.
- */
-
- #include "xlock.h"
- #include <stdio.h>
- #include <math.h>
-
- #define CURVEPOINTS 200 /* number of points on the curve */
- #define SIGMA 1.0
- #define MAXLINES 1000
-
- typedef struct {
- XPoint points[CURVEPOINTS+1];
- } curve;
-
- typedef struct {
- int npoints;
- int nlines;
- int pix;
- double *x;
- double *y;
- int *dx;
- int *dy;
- int head;
- int tail;
- int width;
- int height;
- long startTime;
- curve *curves;
- double *xp;
- double *yp;
- } splinestruct;
-
- static splinestruct splines[MAXSCREENS];
-
- void
- initspline(win)
- Window win;
- {
- int i;
-
- XWindowAttributes xgwa;
- splinestruct *sp = &splines[screen];
-
- sp->startTime = seconds();
- if(points < 2) points=2;
- else if(points > 20) points=20;
- sp->npoints = points;
- if(batchcount > MAXLINES) batchcount = MAXLINES;
- sp->nlines = batchcount+1;
-
- if(!sp->curves) {
- sp->x = (double *) malloc(sizeof(double) * sp->npoints);
- sp->y = (double *) malloc(sizeof(double) * sp->npoints);
- sp->dx = (int *) malloc(sizeof(int) * sp->npoints);
- sp->dy = (int *) malloc(sizeof(int) * sp->npoints);
- sp->xp = (double *) malloc(sizeof(double) * sp->npoints);
- sp->yp = (double *) malloc(sizeof(double) * sp->npoints);
- sp->curves = (curve *) malloc(sizeof(curve) * sp->nlines);
- }
- memset(sp->curves, 0, sp->nlines * sizeof(curve));
-
- XGetWindowAttributes(dsp, win, &xgwa);
- sp->width = xgwa.width;
- sp->height = xgwa.height;
-
- if(sp->width < 100) sp->nlines = 2;
-
- srand(time(NULL));
- for(i=0; i<sp->npoints; i++) {
- sp->x[i] = (double)(rand() % sp->width);
- sp->y[i] = (double)(rand() % sp->height);
- sp->dx[i] = ((rand()%21)-10);
- while(sp->dx[i] == 0) sp->dx[i] = ((rand()%21)-10);
- sp->dy[i] = ((rand()%21)-10);
- while(sp->dy[i] == 0) sp->dy[i] = ((rand()%21)-10);
- }
- sp->head = 0;
- sp->tail = 1;
- XSetForeground(dsp, Scr[screen].gc, BlackPixel(dsp,screen));
- XFillRectangle(dsp, win, Scr[screen].gc, 0, 0, sp->width, sp->height);
- }
-
- void
- drawspline(win)
- Window win;
- {
- double s;
- splinestruct *sp = &splines[screen];
- int i;
-
- for(i=0; i<sp->npoints; i++) {
- sp->x[i] += sp->dx[i];
- sp->y[i] += sp->dy[i];
- if((sp->x[i]<0) || (sp->x[i]>sp->width)) sp->dx[i] = -sp->dx[i];
- if((sp->y[i]<0) || (sp->y[i]>sp->height)) sp->dy[i] = -sp->dy[i];
- }
- kurvp1(sp->npoints, sp->x, sp->y, SIGMA, sp->xp, sp->yp, &s);
- for(i=0; i<CURVEPOINTS; i++) {
- kurvp2((double)i/CURVEPOINTS,s,SIGMA,sp->npoints,sp->x,sp->y,sp->xp,sp->yp,
- &(sp->curves[sp->head].points[i].x),&(sp->curves[sp->head].points[i].y));
- }
-
- XSetForeground(dsp, Scr[screen].gc, Scr[screen].pixels[sp->pix]);
-
- sp->curves[sp->head].points[CURVEPOINTS].x = sp->curves[sp->head].points[0].x;
- sp->curves[sp->head].points[CURVEPOINTS].y = sp->curves[sp->head].points[0].y;
-
- XDrawLines(dsp, win, Scr[screen].gc, sp->curves[sp->head].points, CURVEPOINTS+1, CoordModeOrigin);
-
- sp->head++; if(sp->head >= sp->nlines) sp->head = 0;
-
- sp->curves[sp->tail].points[CURVEPOINTS].x = sp->curves[sp->tail].points[0].x;
- sp->curves[sp->tail].points[CURVEPOINTS].y = sp->curves[sp->tail].points[0].y;
-
- XSetForeground(dsp, Scr[screen].gc, BlackPixel(dsp, screen));
- XDrawLines(dsp,win,Scr[screen].gc,sp->curves[sp->tail].points,CURVEPOINTS+1,CoordModeOrigin);
- sp->tail++; if(sp->tail >= sp->nlines) sp->tail = 0;
-
- if(++sp->pix >= Scr[screen].npixels) sp->pix = 0;
- }
-
-
- /* kurvp1 and kurvp2 create the kurve through a number of points */
- kurvp1(n, x, y, sigma, xp, yp, s)
- int n;
- double *x, *y, sigma, *xp, *yp, *s;
- /*
- * Adapted from A.K. Cline, Comm. ACM 4 (1972) 220
- */
- {
- int nm1,np1,i,ip1,ibak;
- double delx1,delx2,dels1,dx1,dy1,dely1,dely2,dels2,dx2,dy2, sigmap,exps,sinhs,sinhin,diag1,diag2,diagin,spdig1,spdiag,dels;
- double temp[CURVEPOINTS*2];
-
- nm1 = n-2; np1=n;
- delx1 = x[1]-x[0];
- dely1 = y[1]-y[0];
- dels1 = sqrt(pow(delx1, 2.0)+pow(dely1, 2.0));
- dx1 = delx1/dels1; dy1 = dely1/dels1;
- xp[0] = dx1; yp[0] = dy1;
- temp[0] = dels1;
- *s = dels1;
-
- for(i=1; i<n; i++) {
- if(i == n-1) ip1 = 0;
- else ip1 = i+1;
- delx2 = x[ip1]-x[i]; dely2=y[ip1]-y[i];
- dels2 = sqrt(pow(delx2, 2.0) + pow(dely2, 2.0));
- dx2 = delx2/dels2;
- dy2 = dely2/dels2;
- xp[i] = dx2-dx1; yp[i]=dy2-dy1;
- temp[i] = dels2;
- delx1 = delx2; dely1=dely2; dels1=dels2;
- dx1 = dx2; dy1 = dy2;
- (*s)=(*s)+dels1;
- }
-
- xp[0] = xp[0]-dx1; yp[0]=yp[0]-dy1;
- sigmap = fabs(sigma)*(n/(*s));
-
- dels = sigmap*temp[n-1]; exps = exp(dels);
- sinhs = 0.5*(exps-(1.0/exps));
- sinhin = 1.0/(temp[n-1]*sinhs);
- diag1 = sinhin*(dels*0.5*(exps+(1.0/exps))-sinhs);
- diagin = 1.0/diag1;
- spdig1 = sinhin*(sinhs-dels);
- spdiag = 0;
-
- for(i=0; i<n; i++) {
- dels = sigmap*temp[i];
- exps = exp(dels);
- sinhs = 0.5*(exps-(1.0/exps));
- sinhin = 1.0/(temp[i]*sinhs);
- diag2 = sinhin*(dels*(0.5*(exps+(1.0/exps)))-sinhs);
-
- if(i == 0) {
- diagin = 1.0/(diag1+diag2);
- xp[0] = diagin*xp[0];
- yp[0] = diagin*yp[0];
- temp[n] = 0;
- temp[np1] = -diagin*spdig1;
- spdiag = sinhin*(sinhs-dels);
- temp[0] = diagin*spdiag;
- diag1 = diag2;
- }
- if((i<n-1) && (i>0)) {
- diagin = 1.0/(diag1+diag2-(spdiag*temp[i-1]));
- xp[i] = diagin*(xp[i]-(spdiag*xp[i-1]));
- yp[i] = diagin*(yp[i]-(spdiag*yp[i-1]));
- temp[n+i] = -diagin*temp[nm1+i+1]*spdiag;
- spdiag = sinhin*(sinhs-dels);
- temp[i] = diagin*spdiag;
- diag1 = diag2;
- }
- }
-
- temp[nm1] = temp[n+nm1]-temp[nm1];
-
- if(n!=2) {
- for(i=2; i<n; i++) {
- ibak = np1-i-1;
- xp[ibak] = xp[ibak]-temp[ibak]*xp[ibak+1];
- yp[ibak] = yp[ibak]-temp[ibak]*yp[ibak+1];
- temp[ibak] = temp[ibak+n] - temp[ibak]*temp[ibak+1];
- }
- }
- xp[n-1] = (xp[n-1]-(spdig1*xp[0])-(spdiag*xp[nm1]))/
- (diag1+diag2+(spdig1*temp[0])+(spdiag*temp[nm1]));
- yp[n-1] = (yp[n-1]-(spdig1*yp[0])-(spdiag*yp[nm1]))/
- (diag1+diag2+(spdig1*temp[0])+(spdiag*temp[nm1]));
-
- for(i=0; i<=nm1; i++) {
- xp[i] = xp[i] + (temp[i]*xp[n-1]);
- yp[i] = yp[i] + (temp[i]*yp[n-1]);
- }
- }
-
- kurvp2(t, s, sigma, n, x, y, xp, yp, xs, ys)
- double t, s, sigma;
- int n;
- double *x, *y, *xp, *yp;
- short *xs, *ys;
- /*
- * Adapted from A.K. Cline, Comm. ACM 4 (1974) 220
- */
- {
- int flag, i, im1;
- double sigmap, tn, delx, dely, dels, del1, del2, sum, sumdels, savesum, exps, exps1, sinhs, sinhd1, sinhd2;
-
-
- sigmap=fabs(sigma)*(n/s);
- tn=fabs(t*s); i=1; sum=0;
- do {
- delx=x[i]-x[i-1];
- dely=y[i]-y[i-1];
- dels=sqrt((delx*delx)+(dely*dely));
- sumdels=sum+dels;
- flag=(sumdels>=tn);
- savesum=sum;
- sum=sumdels;
- i++;
- } while(!(flag || (i==n)));
- if(flag) {
- sum=savesum;
- i--;
- im1=i-1;
- } else {
- i=0;
- im1=n-1;
- dels=s-sum;
- }
- del1=tn-sum; del2=dels-del1;
- exps1=exp(sigmap*del1);
- sinhd1=0.5*(exps1-1.0/exps1);
- exps=exp(sigmap*del2);
- sinhd2=0.5*(exps-1.0/exps);
- exps=exps1*exps;
- sinhs=0.5*(exps-1.0/exps);
- *xs=(short)((xp[i]*sinhd1+xp[im1]*sinhd2)/sinhs +
- ((x[i]-xp[i])*del1+(x[im1]-xp[im1])*del2)/dels);
- *ys=(short)((yp[i]*sinhd1+yp[im1]*sinhd2)/sinhs +
- ((y[i]-yp[i])*del1+(y[im1]-yp[im1])*del2)/dels);
- }
-
-